#pragma once
#include <oratypes.h>
#include <oci.h>
#include <ocidfn.h>
#include <ocidem.h>

 /* Constants used in this program. */
#define MAX_ITEM_BUFFER_SIZE    33
#define MAX_SELECT_LIST_SIZE    1024
#define MAXBUFLEN               5000
#define ROW_BATCH_SIZE          500000

#if defined(_WIN32)
#define STRNCASECMP memicmp
#else
#define STRNCASECMP strncasecmp
#endif

struct COLUMN
{
    /* Describe */
    //text            colname[MAX_ITEM_BUFFER_SIZE];
    text            *colname;
    ub4             colname_len;
    ub4             colwidth;
    ub2             coltype;
    ub4             buflen;
    ub2             precision;
    ub2             scale;

    /*+ Fetch */
    OCIDefine       *dfnhp;
    OCILobLocator   *blob; //blob locator
    OCILobLocator   *clob; //clob locator
    ub1             *colbuf;    //output variable
    sb2             *indp;
    ub2             *col_retlen;
    ub2             *col_retcode;

    /*+ Point to next column */
    struct          COLUMN *next;
};

static OCIEnv       *envhp  = (OCIEnv *)0;
static OCIServer    *srvhp  = (OCIServer *)0;
static OCIError     *errhp  = (OCIError *)0;
static OCISvcCtx    *svchp  = (OCISvcCtx *)0;
static OCIStmt      *stmhp  = (OCIStmt *)0;
static OCIDescribe  *dschp  = (OCIDescribe *)0;
static OCISession   *sesshp = (OCISession *)0;   

ub4     DEFAULT_ARRAY_SIZE = 1000;
ub4     DEFAULT_LONG_SIZE = 32768;
int     return_code = 0;
FILE    *fp_log = NULL;

#define  MIN(a,b) ((a) > (b) ? (b) : (a))

class CSQLUldr2
{
public:
    CSQLUldr2(void);
    ~CSQLUldr2(void);

    int UnloadData(int argc, const char* argv[]);

private:

 /*global env variables*/


 /*Defined functions*/
    void  checkerr(OCIError *errhp, sword status);
    void  initialize ();
    void  logon (char *v_user,char *v_pass,char *v_host);
    void  logout();
    void  cleanup();
    void  freeColumn(struct COLUMN *col);
    void  printRow(text *fname,OCISvcCtx *svchp,OCIStmt *stmhp,struct COLUMN *col,text *field, int flen,text *record, int rlen, int batch, int header);
    void  printRowInfo(ub4 row);
    void  destr(char *src,char *v_user,char *v_pass,char *v_host);
    void stream_read_clob(OCILobLocator *lobl, FILE *fp);
    void stream_read_blob(OCILobLocator *lobl, FILE *fp);

    //sword preparSql(OCIStmt *stmhp, text *sql_statement);
    sword prepareSql(OCIStmt *stmhp, text *sql_statement);
    sword executeSql(OCISvcCtx *svchp,OCIStmt *stmhp,ub4 execount);
    sword getColumns(FILE *fpctl,OCIStmt *stmhp, struct COLUMN *collist);

    int   convertOption(const ub1 *src, ub1* dst, int mlen);
    ub1   getHexIndex(char c);
    FILE  *openFile(const text *fname, text tempbuf[], int batch);

    static void describe_table (FILE *fpctl,text *tabname);
    static void describe_column(FILE *fpctl,OCIParam *parmp, ub4 parmcnt);
    //sword prepareSql(OCIStmt *stmhp, text *sql_statement);
};

